package org.jeecg.modules.workflow.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.workflow.entity.WfForm;
import org.jeecg.modules.workflow.service.IProcessEngine;
import org.jeecg.modules.workflow.service.ProcessFormService;
import org.jeecg.modules.workflow.service.WfFormService;
import org.jeecg.modules.workflow.service.WorkFlowService;
import org.jeecg.modules.workflow.vo.ModelVO;
import org.jeecg.modules.workflow.vo.ProcessQueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 工作流程控制层
 * Create by Kalvin on 2020/4/20.
 */
@Slf4j
@RestController
@RequestMapping(value = "workflow")
public class WorkflowController {

    @Autowired
    private IProcessEngine processEngine;

    @Resource
    private WfFormService formService;

    @Resource
    private ProcessFormService processFormService;

    @Resource
    private WorkFlowService workFlowService;

    /**
     * 保存模型
     * @param modelVO 模型VO实体
     * @return r
     */
    @PostMapping(value = "save/model")
    public Result saveModel(@RequestBody ModelVO modelVO) {
        final String modelId = workFlowService.create(modelVO);
        return Result.ok("添加成功");
    }

    /**
     * 保存表单
     * @param form 表单VO实体
     * @return r
     */
    @PostMapping(value = "save/form")
    public Result saveForm(@RequestBody WfForm form) {
        if(null == form.getId()) {
            formService.saveForm(form);
        } else{
            formService.updateById(form);
        }
        return Result.ok("操作成功");
    }

    /**
     * 查询表单
     * @return r
     */
    @GetMapping(value = "getform")
    public Result saveForm(@RequestParam String modelId) {
        WfForm wfForm = formService.getOne(new LambdaQueryWrapper<WfForm>().eq(WfForm::getModelId,modelId));
        return Result.ok(wfForm);
    }

    /**
     * 流程管理列表
     * @param processQueryVO 查询参数
     * @return r
     */
    @GetMapping(value = "process/list")
    public Result processList(ProcessQueryVO processQueryVO) {
        return Result.ok(workFlowService.getProcesses(processQueryVO));
    }

    /**
     * 发布/部署流程
     * @param modelId 模型ID
     * @return r
     */
    @PostMapping(value = "deploy/{modelId}")
    public Result deploy(@PathVariable String modelId) {
        return Result.ok(workFlowService.deploy(modelId));
    }

    /**
     * 当前用户启动流程
     * @param deploymentId 流程发布ID
     */
    @GetMapping(value = "process/{deploymentId}/start")
    public Result start(@PathVariable String deploymentId) {
        final String taskId = processEngine.start(deploymentId);
        return Result.ok(taskId);
    }

    /**
     * 删除模型
     * @param modelId 模型ID
     * @return r
     */
    @DeleteMapping(value = "delete")
    public Result delete(@RequestParam(name="id",required=true) String modelId) {
        workFlowService.delete(modelId);
        return Result.ok();
    }

    /**
     * 挂起流程
     * @param deploymentIds 发布ID集合
     * @return r
     */
    @PostMapping(value = "suspend/process")
    public Result suspendProcess(@RequestParam("deploymentIds") List<String> deploymentIds) {
        processEngine.suspendProcessDefinitionByIds(deploymentIds);
        return Result.ok();
    }

    /**
     * 激活流程
     * @param deploymentIds 发布ID集合
     * @return r
     */
    @PostMapping(value = "activate/process")
    public Result activateProcess(@RequestParam("deploymentIds") List<String> deploymentIds) {
        processEngine.activateProcessDefinitionByIds(deploymentIds);
        return Result.ok();
    }

    /**
     * 挂起流程实例
     * @param processInstanceId 流程实例ID
     * @return r
     */
    @PostMapping(value = "suspend/processInstance/{processInstanceId}")
    public Result suspendProcessInstance(@PathVariable String processInstanceId) {
        processEngine.suspendProcessInstance(processInstanceId);
        return Result.ok();
    }

    /**
     * 激活流程实例
     * @param processInstanceId 流程实例ID
     * @return r
     */
    @PostMapping(value = "activate/processInstance/{processInstanceId}")
    public Result activateProcessInstance(@PathVariable String processInstanceId) {
        processEngine.activateProcessInstance(processInstanceId);
        return Result.ok();
    }

    /**
     * 我的流程列表
     * @param processQueryVO 查询参数
     * @return r
     */
    @GetMapping(value = "myprocess/list")
    public Result myProcessList(ProcessQueryVO processQueryVO) {
        processQueryVO.setUsername(((LoginUser) SecurityUtils.getSubject().getPrincipal()).getId());
        return Result.ok(workFlowService.getDeployProcesses(processQueryVO));
    }

    @GetMapping(value = "processInstance/{processInstanceId}")
    public Result processInstance(@PathVariable String processInstanceId) {
        return Result.ok(workFlowService.getHistoricProcessInstanceByProcessInstanceId(processInstanceId));
    }

    /**
     * 流程实例流转意见
     * @param processInstanceId 实例ID
     * @return r
     */
    @GetMapping(value = "processInstance/{processInstanceId}/comments")
    public Result processInstanceComments(@PathVariable String processInstanceId) {
        return Result.ok(workFlowService.getProcessInstanceComments(processInstanceId).getData());
    }

    /**
     * 我的待办列表
     * @param processQueryVO 查询参数
     * @return r
     */
    @GetMapping(value = "mytodo/list")
    public Result myTodoList(ProcessQueryVO processQueryVO) {
        processQueryVO.setUsername(((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername());
        return workFlowService.getTodoTasks(processQueryVO).toR();
    }

    /**
     * 我的已办列表
     * @param processQueryVO 查询参数
     * @return r
     */
    @GetMapping(value = "mydone/list")
    public Result myDoneList(ProcessQueryVO processQueryVO) {
        processQueryVO.setUsername(((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername());
        return workFlowService.getDoneTasks(processQueryVO).toR();
    }

    /**
     * 我的申请列表
     * @param processQueryVO 查询参数
     * @return r
     */
    @GetMapping(value = "myapply/list")
    public Result myApplyList(ProcessQueryVO processQueryVO) {
        processQueryVO.setUsername(((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername());
        return workFlowService.getApplyTasks(processQueryVO).toR();
    }

    /**
     * 撤回任务
     * @param taskId 已办任务ID
     * @return r
     */
    @PostMapping(value = "withdraw/task/{taskId}")
    public Result withdrawTask(@PathVariable String taskId) throws Exception{
        String userName = ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
        workFlowService.withdrawApproval(userName,taskId);
        return Result.ok();
    }

    @PostMapping(value = "revoke/{processInstanceId}")
    public Result revoke(@PathVariable String processInstanceId) throws Exception{
        String userName = ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
        workFlowService.revoke(processInstanceId,userName);
        return Result.ok();
    }
}
